#include "Pch.h"

#include "Dx11Buffers.h"
#include "Dx11Globals.h"

namespace MCD
{
	ID3D11Buffer* Dx11Buffers::createVertexDefault(size_t sizeInBytes, size_t stride)
	{
		MCD_ASSUME(nullptr != getD3D11Device());

		ID3D11Buffer* buff = nullptr;
		D3D11_BUFFER_DESC desc;
		desc.ByteWidth = sizeInBytes;	// size
		desc.Usage = D3D11_USAGE_DEFAULT;	// gpu read/write
		desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;	// vertex buffer
		desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;	// cpu write only
		desc.MiscFlags = 0;	// no misc flags
		desc.StructureByteStride = stride;

		HRESULT hr = getD3D11Device()->CreateBuffer(&desc, nullptr, &buff);

		if(FAILED(hr))
			Log::format(Log::Error, L"Dx11Buffers::createVertexDefault() failed");

		return buff;
	}

	ID3D11Buffer* Dx11Buffers::createVertexDynamic(size_t sizeInBytes, size_t stride)
	{
		MCD_ASSUME(nullptr != getD3D11Device());

		ID3D11Buffer* buff = nullptr;
		D3D11_BUFFER_DESC desc;
		desc.ByteWidth = sizeInBytes;	// size
		desc.Usage = D3D11_USAGE_DYNAMIC;	// gpu read/write
		desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;	// vertex buffer
		desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;	// cpu write only
		desc.MiscFlags = 0;	// no misc flags
		desc.StructureByteStride = stride;

		HRESULT hr = getD3D11Device()->CreateBuffer(&desc, nullptr, &buff);

		if(FAILED(hr))
			Log::format(Log::Error, L"Dx11Buffers::createVertexDynamic() failed");

		return buff;
	}

	ID3D11Buffer* Dx11Buffers::createIndexDefault(size_t sizeInBytes, size_t stride)
	{
		MCD_ASSUME(nullptr != getD3D11Device());

		ID3D11Buffer* buff = nullptr;
		D3D11_BUFFER_DESC desc;
		desc.ByteWidth = sizeInBytes;	// size
		desc.Usage = D3D11_USAGE_DEFAULT;	// gpu read/write
		desc.BindFlags = D3D11_BIND_INDEX_BUFFER;	// index buffer
		desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;	// cpu write only
		desc.MiscFlags = 0;	// no misc flags
		desc.StructureByteStride = stride;

		HRESULT hr = getD3D11Device()->CreateBuffer(&desc, nullptr, &buff);

		if(FAILED(hr))
			Log::format(Log::Error, L"Dx11Buffers::createIndexDefault() failed");

		return buff;
	}

	ID3D11Buffer* Dx11Buffers::createIndexDynamic(size_t sizeInBytes, size_t stride)
	{
		MCD_ASSUME(nullptr != getD3D11Device());

		ID3D11Buffer* buff = nullptr;
		D3D11_BUFFER_DESC desc;
		desc.ByteWidth = sizeInBytes;	// size
		desc.Usage = D3D11_USAGE_DYNAMIC;	// gpu read/write
		desc.BindFlags = D3D11_BIND_INDEX_BUFFER;	// index buffer
		desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;	// cpu write only
		desc.MiscFlags = 0;	// no misc flags
		desc.StructureByteStride = stride;

		HRESULT hr = getD3D11Device()->CreateBuffer(&desc, nullptr, &buff);

		if(FAILED(hr))
			Log::format(Log::Error, L"Dx11Buffers::createIndexDynamic() failed");

		return buff;
	}

	ID3D11Buffer* Dx11Buffers::createConstant(size_t sizeInBytes)
	{
		MCD_ASSUME(nullptr != getD3D11Device());

		ID3D11Buffer* buff = nullptr;
		D3D11_BUFFER_DESC desc;
		desc.ByteWidth = sizeInBytes;	// size
		desc.Usage = D3D11_USAGE_DYNAMIC;	// gpu read/write
		desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;	// constant buffer
		desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;	// cpu write only
		desc.MiscFlags = 0;	// no misc flags

		HRESULT hr = getD3D11Device()->CreateBuffer(&desc, nullptr, &buff);

		if(FAILED(hr))
			Log::format(Log::Error, L"Dx11Buffers::createConstant() failed");

		return buff;
	}

	ID3D11InputLayout* Dx11Buffers::createInputLayout(
		D3D11_INPUT_ELEMENT_DESC* elements,
		size_t elementCnt,
		ID3DBlob* shaderByteCode
		)
	{
		MCD_ASSUME(nullptr != getD3D11Device());

		ID3D11InputLayout* layout = nullptr;

		HRESULT hr = getD3D11Device()->CreateInputLayout(
			elements,
			elementCnt,
			shaderByteCode->GetBufferPointer(),
			shaderByteCode->GetBufferSize(),
			&layout
			);

		if(FAILED(hr))
			Log::format(Log::Error, L"Dx11Buffers::createInputLayout() failed");

		return layout;
	}

}	// namespace MCD